package com.tangzx.builder.abc;

import com.tangzx.builder.abc.string.AbcString;
import com.tangzx.builder.abc.string.MultiName;
import macromedia.asc.embedding.avmplus.ActionBlockConstants;

public class Trait extends AbcElement {

	public static final byte Trait_Slot = 0;
	public static final byte Trait_Method = 1;
	public static final byte Trait_Getter = 2;
	public static final byte Trait_Setter = 3;
	public static final byte Trait_Class = 4;
	public static final byte Trait_Function = 5;
	public static final byte Trait_Const = 6;
	
	public int nameIndex;
	public int kind;
	public int[] data;
	public int[] metadata;
	public Trait(int name_index, int kind, int[] data)
	{
		this.nameIndex = name_index;
		this.kind = kind;
		this.data = data;
	}
	
	public boolean hasMetadata()
	{
		return (getAttrs() & ActionBlockConstants.TRAIT_FLAG_metadata) != 0;
	}
	
	public void addMetadata(int[] metas) 
	{
		this.metadata = metas;
		for (int index : metadata) {
			Metadata m = file.metadata[index];
			if (m.getName().equals("UnMix")) {
				MultiName mn = getMN();
				AbcString s = cpool.getString(mn.params[1]);
				s.setCanMix(false);
				System.out.println("UnMix:" + s);
				break;
			}
		}
	}
	
	public boolean hasMetadata(String name) {
		return getMetadata(name) != null;
	}
	
	public Metadata getMetadata(String name) {
		if (metadata != null)
			for (int index : metadata) {
				Metadata temp = file.metadata[index];
				if (temp.getName().equals(name)) {
					return temp;
				}
			}
		return null;
	}
	
	/**
	 * 获取它的MultiName， 必定是QName
	 * @return
	 */
	public MultiName getMN() {
		return cpool.getMultiName(nameIndex);
	}
	
	@Override
	public String toString() {
		String name = cpool.getMultiName(nameIndex).toString();//cpool.getString(nameIndex).toString();
		if (metadata != null){
			for (int index:metadata) {
				name += ", " + cpool.getString(index).toString();
			}
		}
		return "[" + name + "]";
	}
	
	public int getAttrs()
	{
		return kind >> 4;
	}
	
	public int getTag()
	{
		return kind & 0xf;
	}
	
	public boolean isConstTrait() {
		return (getTag() == ActionBlockConstants.TRAIT_Const);
	}
	
	public int[] getMetadata()
	{
		return this.metadata;
	}
	
	public int getSlotId() {
		assert(getTag() == ActionBlockConstants.TRAIT_Var || getTag() == ActionBlockConstants.TRAIT_Const || getTag() == ActionBlockConstants.TRAIT_Class);
		return data[0];
	}
	
	public int getTypeName() {
		assert(getTag() == ActionBlockConstants.TRAIT_Var || getTag() == ActionBlockConstants.TRAIT_Const);
		return data[1];
	}
	
	public int getValueIndex() {
		assert(getTag() == ActionBlockConstants.TRAIT_Var || getTag() == ActionBlockConstants.TRAIT_Const);
		return data[2];
	}
	
	public int getValueKind() {
		assert(getTag() == ActionBlockConstants.TRAIT_Var || getTag() == ActionBlockConstants.TRAIT_Const);
		return data[3];
	}
	
	public int getDispId() {
		assert(getTag() == ActionBlockConstants.TRAIT_Method || getTag() == ActionBlockConstants.TRAIT_Getter || getTag() == ActionBlockConstants.TRAIT_Setter);
		return data[0];
	}
	
	public int getMethodId() {
		assert(getTag() == ActionBlockConstants.TRAIT_Method || getTag() == ActionBlockConstants.TRAIT_Getter || getTag() == ActionBlockConstants.TRAIT_Setter);
		return data[1];
	}
	
	public int getClassId() {
		assert(getTag() == ActionBlockConstants.TRAIT_Class);
		return data[1];
	}
}
